package cn.test.excel.jxsl;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.collections4.MapUtils;
import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.jexl3.JexlEngine;
import org.jxls.common.Context;
import org.jxls.expression.JexlExpressionEvaluator;
import org.jxls.transform.TransformationConfig;
import org.jxls.transform.Transformer;
import org.jxls.util.JxlsHelper;

import org.springframework.stereotype.Service;

public class JXLSTemplateDataFillServiceImpl {

    private JxlsHelper jxlsHelper;

    private JexlEngine jexlEngine;

    @PostConstruct
    public void JXLSProcessInit() {
        jxlsHelper = JxlsHelper.getInstance();
        Map<String, Object> functionMap = new HashMap<>();
        functionMap.put(JXLSFunction.FUNCTION_NAME, JXLSFunction.getInstance());
        JexlBuilder jexlBuilder = new JexlBuilder();
        jexlBuilder.namespaces(functionMap);
        jexlEngine = jexlBuilder.create();
    }

    public byte[] processToByte(File templateFile, Map<String, Object> dataSource) throws Exception {
        FileInputStream inputStream = new FileInputStream(templateFile);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        doProcess(inputStream, outputStream, dataSource);
        return outputStream.toByteArray();
    }

    public byte[] processToByte(InputStream inputStream, Map<String, Object> dataSource) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        doProcess(inputStream, outputStream, dataSource);
        return outputStream.toByteArray();
    }
//
//    public byte[] processToPdfByte(File templateFile, Map<String, Object> dataSource) throws Exception {
//        byte[] dataByte = processToByte(templateFile, dataSource);
//        return FileUtil.doPdfProcessByAsposeOfExcel(dataByte);
//    }

    public void writeToFile(File templateFile, File outFile, Map<String, Object> dataSource) throws Exception {
        byte[] dataByte = processToByte(templateFile, dataSource);
        FileOutputStream fileOutputStream = new FileOutputStream(outFile);
        fileOutputStream.write(dataByte);
        fileOutputStream.close();
    }

    public void writeToOutputStream(File templateFile, OutputStream outPut, Map<String, Object> dataSource)
            throws Exception {
        FileInputStream inputStream = new FileInputStream(templateFile);
        doProcess(inputStream, outPut, dataSource);
    }

    public void writeToOutputStream(InputStream inputStream, OutputStream outPut, Map<String, Object> dataSource)
            throws Exception {
        doProcess(inputStream, outPut, dataSource);
    }

    /**
     * 根据模板将数据填充至输出流中
     *
     * @param inputStream
     * @param outputStream
     * @param dataSource
     * @throws Exception
     */
    private void doProcess(InputStream inputStream, OutputStream outputStream, Map<String, Object> dataSource)
            throws Exception {
        Context dataContext = new Context();
        if (MapUtils.isNotEmpty(dataSource)) {
            dataSource.forEach((k, v) -> dataContext.putVar(k, v));
        }
        Transformer transformer = jxlsHelper.createTransformer(inputStream, outputStream);
        TransformationConfig transformationConfig = transformer.getTransformationConfig();
        JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator) transformationConfig.getExpressionEvaluator();
        evaluator.setJexlEngine(jexlEngine);
        jxlsHelper.setUseFastFormulaProcessor(false).processTemplate(dataContext, transformer);
    }
}
